package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"sync"

	reflectPb "gitee.com/wu-jin-feng/kinfu/fgin/demos/fjaeger_test/client/pb"
	"github.com/gin-gonic/gin"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	"gitee.com/wu-jin-feng/kinfu/fgin"
)

var (
	demoGrpcClient reflectPb.DemoServiceClient
)

// 例子，客户端连接grpc失败进行链接重启
func handleGRPCError(serviceName, tag string, grpcErr error) {
	fmt.Println("1111", grpcErr.Error())
	err, ok := status.FromError(grpcErr)
	if !ok {
		fmt.Println("格式化grpc错误失败")
		return
	}
	switch err.Code() {
	case codes.Unavailable:
		log.Println("gRPC server is unavailable, the connection was refused.")
		// 找不到服务，可能瞬时的，可以重试，或者创建新链接
		restartObj, err := fgin.GetRestartGrpcObj(serviceName)
		if err != nil {
			log.Println(err)
			return
		}
		conn, err := restartObj.RestartFgrpcClientConn()
		if err != nil {
			log.Println(err)
			return
		}
		demoGrpcClient = reflectPb.NewDemoServiceClient(conn)
	case codes.DeadlineExceeded:
		log.Println("The request has timed out.")
	case codes.Canceled:
		log.Println("The request was canceled.")
		// 服务端取消操作,可能是服务端conn已关闭
		restartObj, err := fgin.GetRestartGrpcObj(serviceName)
		if err != nil {
			log.Println(err)
			return
		}
		conn, err := restartObj.RestartFgrpcClientConn()
		if err != nil {
			log.Println(err)
			return
		}
		demoGrpcClient = reflectPb.NewDemoServiceClient(conn)
	default:
		log.Printf("gRPC error: %v", err.Message())
	}
}

func main() {
	f := fgin.Fgin{}
	r := f.GetHttpServer("./test.yaml")
	r.GET("/test", func(ctx *gin.Context) {
		ctx.JSON(200, "test success")
	})
	grpcConn, err := f.GetFgrpcClientConn("fjaeger_test_grpc_server")
	// grpcConn, err := fgin.GetGrpcClientConnV2("fjaeger_test_grpc_server", "fjaeger_test_grpc_server", "10.96.19.168:8011")
	if err != nil {
		panic(err)
	}
	demoGrpcClient = reflectPb.NewDemoServiceClient(grpcConn)
	r.GET("/test2", func(ctx *gin.Context) {
		log := f.GetFginLogger()
		log.Info("哈哈哈哈哈")
		grpcCtx := fgin.GetGrpcCtx(ctx.Request.Context())
		res, err := demoGrpcClient.GetScheme(grpcCtx, &reflectPb.GetSchemeReq{
			Path: "321222",
			Info: &reflectPb.GetSchemeRespInfo{
				Info: "哈哈哈哈",
				Name: "gogo",
			},
		})
		if err != nil {
			// defer handleGRPCError("fjaeger_test_grpc_server", "fjaeger_test_grpc_server", err)
			// defer func() {
			// 	grpcConn, err := f.GetFgrpcClientConn("fjaeger_test_grpc_server")
			// 	if err != nil {
			// 		panic(err)
			// 	}
			// 	demoGrpcClient = reflectPb.NewDemoServiceClient(grpcConn)
			// }()
			fgin.ReturnJson(ctx, 500, "grpc fail", err)
			return
		}
		fgin.ReturnJson(ctx, 200, res, nil)

	})
	r.GET("/test3", func(ctx *gin.Context) {
		req, _ := http.NewRequest("GET", "http://localhost:8013/test", nil)
		req.Header = fgin.GetCtxToHeader(ctx.Request.Context())
		resp, err := (&http.Client{}).Do(req)
		if err != nil {
			fgin.ReturnJson(ctx, 400, "fail", err)
		}
		defer resp.Body.Close()
		respByte, _ := io.ReadAll(resp.Body)
		fgin.ReturnJson(ctx, 200, fmt.Sprintf("test3 is ok, 8013:%s", respByte), nil)
	})

	r.GET("test4", func(ctx *gin.Context) {
		var wg sync.WaitGroup
		for i := 0; i < 1000; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				grpcCtx := fgin.GetGrpcCtx(ctx.Request.Context())
				res, err := demoGrpcClient.GetScheme(grpcCtx, &reflectPb.GetSchemeReq{
					Path: "321222",
					Info: &reflectPb.GetSchemeRespInfo{
						Info: "哈哈哈哈",
						Name: "gogo",
					},
				})
				if err != nil {
					// defer handleGRPCError("fjaeger_test_grpc_server", "fjaeger_test_grpc_server", err)
					defer func() {
						grpcConn, err := f.GetFgrpcClientConn("fjaeger_test_grpc_server")
						if err != nil {
							panic(err)
						}
						demoGrpcClient = reflectPb.NewDemoServiceClient(grpcConn)
					}()
					fgin.ReturnJson(ctx, 500, "grpc fail", err)
					return
				}
				fgin.ReturnJson(ctx, 200, res, nil)
			}()
			wg.Wait()
		}
	})

	f.Run(r)

}
